#pragma once

#include <iostream>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

class InetAddr
{
private:
    void ToHost(const struct sockaddr_in &addr)
    {
        // ntohs()函数的作用是将一个16位数由网络字节顺序转换为主机字节顺序
        // htonl()  l是32位 s是16位 n是网络 h是主机序列
        _port = ntohs(addr.sin_port);

        // inet_ntoa (struct in_addr);
        // 返回点分十进制的字符串在静态内存中的指针
        // (当多个线程访问时有可能出现前一个调用该函数产生的结果被后面再次调用的结果覆盖)
        //_ip = inet_ntoa(addr.sin_addr);

        // 使用自己创建的缓冲区，避免共用一个缓冲区导致数据被覆盖的问题
        char ip_buf[32];
        inet_ntop(AF_INET, &addr.sin_addr, ip_buf, sizeof(ip_buf));
        _ip = ip_buf;
    }

public:
    InetAddr()
    {
    }

    InetAddr(const struct sockaddr_in &addr)
        : _addr(addr)
    {
        ToHost(addr);
    }

    std::string Ip()
    {
        return _ip;
    }

    bool operator==(const InetAddr &addr) const
    {
        return (addr._port == _port && addr._ip == _ip);
    }

    struct sockaddr_in Addr()
    {
        return _addr;
    }

    std::string AddrStr()
    {
        return Ip() + std::to_string(port());
    }

    uint16_t port()
    {
        return _port;
    }

    ~InetAddr()
    {
    }

private:
    std::string _ip;
    uint16_t _port;
    struct sockaddr_in _addr;
};